<template>
  <div id="progressChart" :style="{'min-height': height + 'px'}">
    <div v-if="spinning" class="mask">
      <a-spin :spinning="spinning" tip="Loading..." />
    </div>
    <div v-if="title" class="chart-title">{{title}}</div>
    <div v-if="!data.length && !spinning" :style="{'min-height': height + 'px'}" class="no-box">--暂无数据--</div>
    <div v-if="visible" :id="container"></div>
  </div>
</template>
<script lang='ts'>
import { Component, Watch, Vue, Prop } from 'vue-property-decorator';
import { Chart } from '@antv/g2';

@Component
export default class ProgressChart extends Vue {
  @Prop({ type: String, default: '' }) title!: string; // 图表标题
  @Prop({ type: String, default: 'progress' }) container!: string; // 渲染chart的节点id
  @Prop({ type: Number, default: 200 }) height!: number; // 高度
  @Prop({ type: Object, default: () => ({ }) }) chartOptions!: any; // Chart配置参数
  @Prop({ type: Array, default: () => [20, 40, 20, 55] }) padding!: number[]; // chart的padding值
  @Prop({ type: Array, default: () => [] }) data!: any[]; // 数据源
  @Prop({ type: String }) valueName!: string; // 数据源的属性名，y轴。值
  @Prop({ type: String }) keyName!: string; // 数据源的属性名，x轴。

  visible: boolean = true
  spinning: boolean = true

  @Watch('data')
  dataChange () {
    this.spinning = true
    this.visible = false
    setTimeout(() => {
      this.visible = !!this.data.length
      this.$nextTick(() => {
        if (this.data.length) {
          this.initTopFiveChart()
        } else {
          // 没数据
          this.spinning = false
        }
      })
    }, 0);
  }

  initTopFiveChart () {
    const chart = new Chart({
      container: this.container,
      padding: this.padding,
      height: this.height,
      autoFit: true,
      ...this.chartOptions
    });
    // 服务端排好了顺序，但g2的渲染是反过来的
    chart.data(JSON.parse(JSON.stringify(this.data)).reverse());
    chart.scale(this.valueName, { nice: true });
    chart.coordinate().transpose();
    chart.tooltip({
      showTitle: false,
      showMarkers: false
    });
    chart.axis(this.valueName, false);
    chart.axis(this.keyName, {
      line: null,
      label: {
        style: {
          fill: '#fff'
        },
        formatter: (text: string, item: any, index: number) => {
          return text.length > 8 ? text.slice(0, 8) + '...' : text
        }
      }
    });
    chart.interaction('active-region');
    chart
      .interval()
      .position(`${this.keyName}*${this.valueName}`)
      .size(5)
      .tooltip(`${this.keyName}*${this.valueName}`, (a: any, b: any) => ({
        name: a,
        value: b
      }))
      .color('#1EDDDA')
      .animate({
        appear: {
          duration: 3000
        }
      })
    chart.render();
    this.spinning = false
  }
}
</script>
<style lang='scss' scoped>
#progressChart {
  position: relative;
  .mask {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0);
    display: flex;
    justify-content: center;
    align-items: center;
    z-index: 9999;
  }
}
.chart-title {
  padding: 20px 0 20px;
  font-weight: 600;
  font-size: 15px;
}
.no-box {
  display: flex;
  justify-content: center;
  align-items: center;
}
</style>
